package com.google.code.filecomparator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class FileComparator {

	private static final int ARGS = 3;

	public static void main(String[] args) {

		// Checks the number of command-line arguments.
		if (args.length != ARGS) {
			System.err.println(String.format("Usage: java com.google.code.filecomparator.FileComparator <source-path-1> <source-path-2> <destination-path>] The number of the arguments (%s) is less than the required %s", args.length, ARGS));
			System.exit(1);
		}

		final String sourcePath1 = args[0];
		final String sourcePath2 = args[1];

		final String destinationPath = args[2];

		// The first file.
		final File file1 = new File(sourcePath1);

		// The second file.
		final File file2 = new File(sourcePath2);

		// The destination file that contains the common words.
		final File destinationFile = new File(destinationPath);

		// Set of words in the first file.
		final Set<String> words = new HashSet<String>();
		BufferedReader bufferedReader = null;

		// Read the first file and keep all words.
		try {
			bufferedReader = new BufferedReader(new FileReader(file1));
			String line = null;
			while ((line = bufferedReader.readLine()) != null) {
				words.add(line);
			}
		} catch (FileNotFoundException fnfe) {
			System.err.println(String.format("File %s does not exist.", sourcePath1));
			fnfe.printStackTrace();
			System.exit(2);
		} catch (IOException ioe) {
			System.err.println("An I/O error occured while reading the first file.");
			ioe.printStackTrace();
			System.exit(3);
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException ioe) {
					System.err.println("An I/O error occured while closing the first file.");
					ioe.printStackTrace();
				}
				bufferedReader = null;
			}
		}

		// Set of two files common words.
		final Set<String> commonWords = new HashSet<String>();

		// Read the second file and keep only the common words.
		try {
			bufferedReader = new BufferedReader(new FileReader(file2));
			String line = null;
			while ((line = bufferedReader.readLine()) != null) {
				if (words.contains(line)) {
					commonWords.add(line);
				}
			}
		} catch (FileNotFoundException fnfe) {
			System.err.println(String.format("File %s does not exist.", sourcePath2));
			fnfe.printStackTrace();
			System.exit(2);
		} catch (IOException ioe) {
			System.err.println("An I/O error occured while reading the second file.");
			ioe.printStackTrace();
			System.exit(3);
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException ioe) {
					System.err.println("An I/O error occured while closing the second file.");
					ioe.printStackTrace();
					System.exit(3);
				}
				bufferedReader = null;
			}
		}

		// Order the common words.
		final List<String> orderedCommonWords = new ArrayList<String>(commonWords);
		Collections.sort(orderedCommonWords);

		PrintWriter printWriter = null;

		// And write them to the destination file.
		try {
			printWriter = new PrintWriter(destinationFile);
			for (final String word : orderedCommonWords) {
				printWriter.println(word);
			}
		} catch (IOException ioe) {
			System.err.println("An I/O error occured while writing the destination file.");
			ioe.printStackTrace();
			System.exit(3);
		} finally {
			if (printWriter != null) {
				printWriter.close();
			}
		}
	}
}
